package cn.caidabao.gb.controller;

import cn.caidabao.gb.bean.*;
import cn.caidabao.gb.component.media.ZLMMediaApi;
import cn.caidabao.gb.component.sip.server.request.send.ByeMessageSender;
import cn.caidabao.gb.component.sip.server.request.send.InviteMessageSender;
import cn.caidabao.gb.component.sip.server.request.send.PlaybackCmdSender;
import cn.caidabao.gb.component.sip.server.request.send.QueryMessageSender;
import cn.caidabao.gb.component.sip.server.storage.SessionStorage;
import cn.caidabao.gb.config.ZLMConfig;
import cn.caidabao.gb.util.InviteObjectUtils;
import cn.caidabao.gb.util.MessageObjectUtil;
import cn.caidabao.gb.util.PlaybackCmdObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;


@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private ZLMMediaApi zlmMediaApi;
    @Autowired
    private SessionStorage sessionStorage;
    @Autowired
    private ZLMConfig zlmConfig;
    @Resource
    private InviteMessageSender inviteMessageSender;
    @Resource
    private ByeMessageSender byeMessageSender;
    @Resource
    private QueryMessageSender queryMessageSender;
    @Resource
    private PlaybackCmdSender playbackCmdSender;

    @GetMapping("/invite")
    public DeferredResult<String> invite(String deviceId, String channelId) throws IOException{
        GBSipRegisterSession session = sessionStorage.getSession(deviceId);
        DeferredResult<String> result = new DeferredResult<>();
        if (session==null){
            result.setResult("no device found");
            return result;
        }
        MediaResponse mediaResponse = zlmMediaApi.openRtpServer(channelId);
        if (!mediaResponse.isSuccess()){
            result.setResult(mediaResponse.getErrorMsg());
            return result;
        }
        String ip = mediaResponse.getIp();
        String port = mediaResponse.getPort();
        InviteObject extraData = InviteObjectUtils.generateLivingInviteObject(ip, Integer.parseInt(port), channelId);
        inviteMessageSender.sendAsync(session, extraData)
                .callBack(res->result.setResult(res?"sucess":"fail"));
        return result;
    }

    @GetMapping("/bye")
    public DeferredResult<String> bye(String deviceId,String channelId){
        GBSipRegisterSession session = sessionStorage.getSession(deviceId);
        DeferredResult<String> result = new DeferredResult<>();
        if (session==null){
            result.setResult("no device found");
            return result;
        }
        InviteObject extraData = new InviteObject();
        extraData.setChanelId(channelId);
        extraData.setMediaPort(0);
        extraData.setMediaIp(zlmConfig.getIp());
        OGSipCallIdCallBack<Boolean> callBack = byeMessageSender.sendAsync(session, extraData);
        callBack.callBack(res->result.setResult(res?"sucess":"fail"));
        return result;
    }

    @GetMapping("/query")
    public DeferredResult<String> query(String deviceId){
        GBSipRegisterSession session = sessionStorage.getSession(deviceId);
        DeferredResult<String> result = new DeferredResult<>();
        if (session==null){
            result.setResult("no device found");
            return result;
        }
        QueryObject queryObject = MessageObjectUtil.generateCatalogObject(deviceId);
        queryMessageSender.sendAsync(session,queryObject).callBack(res->result.setResult(String.valueOf(res)));
        return result;
    }

    @GetMapping("/recordInfo")
    public DeferredResult<String> recordInfo(String deviceId,String channelId,Integer dayCount){
        GBSipRegisterSession session = sessionStorage.getSession(deviceId);
        DeferredResult<String> result = new DeferredResult<>();
        if (session==null){
            result.setResult("no device found");
            return result;
        }
        QueryObject queryObject = MessageObjectUtil.generateRecordInfoObject(channelId,LocalDateTime.now().minusDays(dayCount),LocalDateTime.now());
        queryMessageSender.sendAsync(session,queryObject).callBack(res->result.setResult(String.valueOf(res)));
        return result;
    }

    @GetMapping("/inviteHistory")
    public DeferredResult<String> inviteHistory(String deviceId,String channelId) throws IOException {
        GBSipRegisterSession session = sessionStorage.getSession(deviceId);
        DeferredResult<String> result = new DeferredResult<>();
        if (session==null){
            result.setResult("no device found");
            return result;
        }
        MediaResponse mediaResponse = zlmMediaApi.openRtpServer(channelId);
        if (!mediaResponse.isSuccess()){
            result.setResult(mediaResponse.getErrorMsg());
            return result;
        }
        String ip = mediaResponse.getIp();
        String port = mediaResponse.getPort();
        InviteObject extraData = InviteObjectUtils.generatePlaybackInviteObject(ip, Integer.parseInt(port), channelId,1751719571L,1751719871L);
        inviteMessageSender.sendAsync(session, extraData)
                .callBack(res->result.setResult(res?"sucess":"fail"));
        return result;
    }

    @GetMapping("/drag")
    public DeferredResult<Object> drag(String deviceId,String channelId,Integer dragSeconds){
        GBSipRegisterSession session = sessionStorage.getSession(deviceId);
        DeferredResult<Object> result = new DeferredResult<>();
        if (session==null){
            result.setResult("no device found");
            return result;
        }
        PlaybackCmdObject playbackCmdObject = PlaybackCmdObjectUtils.generateDragObject(channelId, dragSeconds);
        playbackCmdSender.sendAsync(session,playbackCmdObject).callBack(res->result.setResult(res));
        return result;
    }

    @GetMapping("/getAllDevices")
    public Object getAllDevices(@RequestParam(required = false) String deviceId){
        return sessionStorage.getAllDevices(deviceId);
    }

}
